package com.luxf.base.domainevent;

import com.luxf.base.domainevent.constants.SentStatus;
import com.luxf.base.domainevent.model.DomainEventNotice;
import com.luxf.base.domainevent.model.MessageSentHistory;
import com.luxf.base.domainevent.repository.MessageSentHistoryRepository;
import com.luxf.base.domainevent.utils.EventNoticeUtils;

import javax.annotation.Resource;
import java.time.Instant;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author fast66
 * 2021-05-28 17:05
 **/
public class EventNoticeManager {

    @Resource
    private MessageSentHistoryRepository messageSentHistoryRepository;

    public void markSuccess(DomainEventNotice eventNotice) {
        changeStatus(eventNotice, SentStatus.SUCCESS);
    }

    public void markFail(DomainEventNotice eventNotice) {
        changeStatus(eventNotice, SentStatus.FAIL);
    }

    public List<DomainEventNotice> findUnsentNotices() {
        List<SentStatus> statusList = Arrays.asList(SentStatus.NONE, SentStatus.FAIL);
        return messageSentHistoryRepository.findAllByStatusInOrderByCreatedDateAsc(statusList)
                .stream()
                .map(MessageSentHistory::getDomainEventNotice)
                .collect(Collectors.toList());
    }

    public Optional<DomainEventNotice> findUnsentNotice(DomainEventNotice eventNotice) {
        Optional<MessageSentHistory> historyOptional = messageSentHistoryRepository.findById(EventNoticeUtils.getMessageId(eventNotice));
        return historyOptional.filter(history -> SentStatus.SUCCESS != history.getStatus())
                .map(MessageSentHistory::getDomainEventNotice);
    }

    public void markNone(DomainEventNotice eventNotice) {
        MessageSentHistory history = MessageSentHistory.createNoneStateMessage(eventNotice);
        messageSentHistoryRepository.save(history);
    }

    private boolean exist(DomainEventNotice notice) {
        Optional<MessageSentHistory> messageSentHistory = messageSentHistoryRepository.findById(EventNoticeUtils.getMessageId(notice));
        return messageSentHistory.isPresent();
    }

    private void changeStatus(DomainEventNotice eventNotice, SentStatus status) {
        String messageId = EventNoticeUtils.getMessageId(eventNotice);
        if (exist(eventNotice)) {
            MessageSentHistory history = messageSentHistoryRepository.getOne(messageId);
            history.setStatus(status);
            history.setLastModifiedDate(Instant.now());
            messageSentHistoryRepository.save(history);
            return;
        }
        throw new NullPointerException("不存在的领域通知:" + messageId);
    }
}
